home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
kernel.zip
/
K1.C
< prev
next >
Wrap
Text File
|
1986-11-25
|
28KB
|
750 lines
/*
Listing 1 Scheduling Algorithm
(C) Copyright 1986 Ken Berry.
All rights reserved.
Copies may be made for non-commercial, private use only.
*/
#define _F 0 /* false */
#define _T 1 /* true */
#define _E -1 /* error */
#define _NULL 0 /* null pointer */
typedef char pointer; /* pointer type */
typedef char logical; /* logical type */
typedef unsigned selector; /* 8086 selector type */
struct sys_parm /* register storage block for 8086 interface */
{
union {unsigned sys_rax; struct {char sys_ral, sys_rah;} sys_byt;} sys_ra;
union {unsigned sys_rbx; struct {char sys_rbl, sys_rbh;} sys_byt;} sys_rb;
union {unsigned sys_rcx; struct {char sys_rcl, sys_rch;} sys_byt;} sys_rc;
union {unsigned sys_rdx; struct {char sys_rdl, sys_rdh;} sys_byt;} sys_rd;
#define sys_ax sys_ra.sys_rax
#define sys_al sys_ra.sys_byt.sys_ral
#define sys_ah sys_ra.sys_byt.sys_rah
#define sys_bx sys_rb.sys_rbx
#define sys_bl sys_rb.sys_byt.sys_rbl
#define sys_bh sys_rb.sys_byt.sys_rbh
#define sys_cx sys_rc.sys_rcx
#define sys_cl sys_rc.sys_byt.sys_rcl
#define sys_ch sys_rc.sys_byt.sys_rch
#define sys_dx sys_rd.sys_rdx
#define sys_dl sys_rd.sys_byt.sys_rdl
#define sys_dh sys_rd.sys_byt.sys_rdh
unsigned sys_bp; /* base pointer */
unsigned sys_si; /* source index */
unsigned sys_di; /* destination index */
unsigned sys_sp; /* stack pointer */
unsigned sys_cs; /* code segment */
unsigned sys_ds; /* data segment */
unsigned sys_ss; /* stack segment */
unsigned sys_es; /* extra segment */
unsigned sys_pf; /* 80286 processor flags */
#define SYS_OF 0x0800 /* overflow flag- 1: lost significance */
#define SYS_DF 0x0400 /* direction flag- 1: strings auto-decrement */
#define SYS_IF 0x0200 /* interrupt flag- 1: enable interrupts */
#define SYS_TF 0x0100 /* trap flag- 1: interrupt every instruction */
#define SYS_SF 0x0080 /* sign flag- 1: result negative */
#define SYS_ZF 0x0040 /* zero flag- 1: result 0 */
#define SYS_AF 0x0010 /* auxiliary carry flag- 1: carry from bit 3 */
#define SYS_PF 0x0004 /* parity flag- 1: even number of 1's */
#define SYS_CF 0x0001 /* carry flag- 1: carry from bit 8 or 16 */
unsigned sys_sw; /* status word */
#define SYS_TS 0x0008 /* task switch */
#define SYS_EM 0x0004 /* processor extension emulation */
#define SYS_MP 0x0002 /* monitor processor extension */
#define SYS_PE 0x0001 /* protection enable */
unsigned sys_ip; /* instruction pointer */
unsigned sys_res; /* unused */
};
struct t_xstck
{
unsigned t_xbase; /* application stack base (overflow detection) */
unsigned t_xes; /* es */
unsigned t_xbp; /* bp */
unsigned t_xdi; /* di */
unsigned t_xsi; /* si */
unsigned t_xdx; /* dx */
unsigned t_xcx; /* cx */
unsigned t_xbx; /* bx */
unsigned t_xax; /* ax */
unsigned t_xds; /* ds */
unsigned t_xip; /* ip */
unsigned t_xcs; /* cs */
unsigned t_xpf; /* pf */
unsigned t_retip; /* return address */
};
struct t_task
{
char t_type; /* task type */
#define T_X 0x80 /* execute queue */
#define T_W 0x40 /* wait queue */
#define T_P 0x20 /* priority queue */
#define T_SW 0x10 /* secondary wait queue */
#define T_ATASK 0x01 /* abreviated task */
unsigned t_wttk; /* wait tick count */
unsigned t_cls; /* priority queue index */
struct t_task *t_pqtsk,*t_nqtsk; /* queue linkage */
struct t_task *t_ratsk,*t_pstsk,*t_nstsk,*t_fdtsk,*t_ldtsk; /* family */
struct sys_parm t_ps; /* processor status */
unsigned t_xtm0; /* execution time accumulator */
unsigned t_xtm1;
unsigned t_xtm2;
pointer *t_axstk; /* execution stack pointer */
};
extern pointer *sys_task; /* current task control table pointer */
#define _tsk ( ( struct t_task * ) sys_task ) /* task control table ref */
#define T_SCLS 4 /* number of scheduling classes */
struct t_scls /* scheduling class queue */
{
unsigned t_sfrq; /* scheduling frequency */
int t_sct; /* queue length */
struct t_task *t_fqtsk,*t_lqtsk; /* queue header */
};
struct t_schd /* scheduling control table */
{
int t_xct; /* execution queue length */
struct t_task *t_fxtsk, *t_lxtsk; /* execution queue header */
int t_wct; /* wait queue length */
struct t_task *t_fwtsk, *t_lwtsk; /* wait queue header */
int t_swct; /* secondary wait queue length */
struct t_task *t_fswtsk, *t_lswtsk; /* secondary wait queue header */
int t_sclsl; /* scheduling class index limit */
struct t_scls **t_sclsp; /* scheduling class array pointer */
};
extern pointer *sys_tsch; /* task scheduling control table pointer */
#define _tschd ( ( struct t_schd * ) sys_tsch ) /* quick pointer */
/*
t__krnl * security kernel *
*/
t__krnl()
/*
This is the security kernel. It never returns, being the most trusted
software in the system. The current contents in t__crtss and t__crtsp
are used to set the stack for when the current task is resumed. */
{
extern logical t_astrm; /* tick termination flag */
extern selector t__crtss; /* current task ss storage */
extern pointer *t__crtsp; /* current task sp storage */
extern unsigned tmr_tkct; /* tick clock */
int xtskct; /* task queue count (at entry) */
int ttc; /* task termination code */
_tsk -> t_ps.sys_ss = t__crtss; /* set current task stack */
_tsk -> t_ps.sys_sp = t__crtsp;
while(_T) /* find executable task */
{
xtskct = _tschd -> t_xct; /* save task count */
if ( t_astrm ) t__wtst( tmr_tkct ); /* process wait tasks */
if ( xtskct == 0 ) t__sch(); /* schedule application tasks if necessary */
sys_task = _tschd -> t_fxtsk; /* set next task address */
if ( sys_task != _NULL ) /* test for executable task available */
{
_tschd -> t_xct--; /* decrement executing task count */
_tschd -> t_fxtsk = _tsk -> t_nqtsk; /* delink task */
if ( _tschd -> t_fxtsk == _NULL )
_tschd -> t_lxtsk = _NULL;
else _tschd -> t_fxtsk -> t_pqtsk = _NULL;
_tsk -> t_type &= ~T_X; /* indicate task not in execution queue */
ttc = t__xtsk( sys_task ); /* execute application task */
if ( !sys_task ) continue; /* test for task terminated */
if ( ttc < 0 ) t__inxq(); /* insert task into execution queue */
else if ( ttc == 0 ) t__inpq(); /* insert task into priority queue */
else t__inwq( ttc ); /* insert into wait queue */
}
}
}
/*
t__wtst test waiting tasks
*/
t__wtst( tc)
unsigned tc;
/*
The wait queue is traversed. All tasks with a wait value of tc are executed.
_F is always returned. */
{
while(_T) /* traverse wait queue */
{
sys_task = _tschd -> t_fwtsk; /* set current task pointer */
if ( !sys_task ) break; /* test for no waiting tasks */
_tsk -> t_type &= ~T_W; /* remove task from wait queue */
_tsk -> t_type |= T_X; /* indicate task in execution queue */
if ( _tsk -> t_wttk > tc ) break; /* test for effective end of list */
--_tschd -> t_wct; /* decrement waiting task count */
_tschd -> t_fwtsk = _tsk -> t_nqtsk; /* delink from wait queue */
if ( _tsk -> t_nqtsk == _NULL )
_tschd -> t_lwtsk = _NULL;
else _tsk -> t_nqtsk -> t_pqtsk = _NULL;
_tsk -> t_pqtsk = _NULL; /* insert at top of execution queue */
_tsk -> t_nqtsk = _tschd -> t_fxtsk;
_tschd -> t_fxtsk = sys_task;
++_tschd -> t_xct; /* increment executable task count */
if ( _tschd -> t_lxtsk == _NULL )
_tschd -> t_lxtsk = sys_task;
else _tsk -> t_nqtsk -> t_pqtsk = sys_task;
}
return _F; /* return */
}
/*
t__sch schedule task
*/
t__sch()
/*
This function searches the priority queues and links tasks ready for execution
into the execution queue. The return is always _F. */
{
struct t_scls **a; /* priority queue pointer array pointer */
struct t_scls *q; /* priority queue pointer */
int i,j; /* iteration variables */
a = _tschd -> t_sclsp; /* set pointer array address */
/* while(_T) * nonterminating ta